#include <iostream>
#include <set>
#include <algorithm>
#include "deck.h"
#include "game_log.h"

static int mj_arr[] = 
{	
	//1~9万
	11,12,13,14,15,16,17,18,19,
	11,12,13,14,15,16,17,18,19,
	11,12,13,14,15,16,17,18,19,
	11,12,13,14,15,16,17,18,19,

	//1~9条
	31,32,33,34,35,36,37,38,39,
	31,32,33,34,35,36,37,38,39,
	31,32,33,34,35,36,37,38,39,
	31,32,33,34,35,36,37,38,39,

	//1~9饼
	51,52,53,54,55,56,57,58,59,
	51,52,53,54,55,56,57,58,59,
	51,52,53,54,55,56,57,58,59,
	51,52,53,54,55,56,57,58,59, 
};

void Deck::fill()
{
    mjs.clear();
    for(int i = 0; i < 108; i++)
    {
		Mj mj(mj_arr[i]);
		mjs.push_back(mj);
    }
}


bool Deck::shuffle(int seed)
{
   srand(time(NULL) + seed);
   random_shuffle(mjs.begin(), mjs.end());
   return true;
}


int Deck::count() const
{
    return mjs.size();	
}

bool Deck::pop(Mj &mj)
{
	if(!count())
		return false;
         mj = mjs.back();
         mjs.pop_back();
	 return true;
}

void Deck::get_player_hole_mjs(HoleMjs &_hole_mjs)
{
   Mj mj;
   _hole_mjs.clear();
   for(int i=0;i<13;i++)
   {
       pop(mj);
       _hole_mjs.add_mj(mj);
   }
   _hole_mjs.sort();
}

void Deck::pei_player_hole_mjs1(HoleMjs &_hole_mjs)
{
	
	_hole_mjs.clear();
	
	Mj mj1(S1);
	Mj mj2(S1);	
	Mj mj3(S1);
	
	Mj mj4(S3);
	Mj mj5(S3);
	Mj mj6(S3);
	
	Mj mj7(S5);
	Mj mj8(S5);
	Mj mj9(S5);
	
	Mj mj10(S7);
	Mj mj11(S7);
	Mj mj12(S7);
	
	Mj mj13(S8);		

	_hole_mjs.add_mj(mj1);
	_hole_mjs.add_mj(mj2);
	_hole_mjs.add_mj(mj3);
	_hole_mjs.add_mj(mj4);
	_hole_mjs.add_mj(mj5);
	_hole_mjs.add_mj(mj6);
	_hole_mjs.add_mj(mj7);
	_hole_mjs.add_mj(mj8);
	_hole_mjs.add_mj(mj9);
	_hole_mjs.add_mj(mj10);
	_hole_mjs.add_mj(mj11);
	_hole_mjs.add_mj(mj12);
	_hole_mjs.add_mj(mj13);
}

void Deck::pei_player_hole_mjs2(HoleMjs &_hole_mjs)
{
	_hole_mjs.clear();
	
	Mj mj1(T1);
	Mj mj2(T1);	
	Mj mj3(T1);
	
	Mj mj4(T3);
	Mj mj5(T3);
	Mj mj6(T3);
	
	Mj mj7(W5);
	Mj mj8(W5);
	Mj mj9(W5);
	
	Mj mj10(W7);
	Mj mj11(W7);
	Mj mj12(W7);
	
	Mj mj13(T8);			

	_hole_mjs.add_mj(mj1);
	_hole_mjs.add_mj(mj2);
	_hole_mjs.add_mj(mj3);
	_hole_mjs.add_mj(mj4);
	_hole_mjs.add_mj(mj5);
	_hole_mjs.add_mj(mj6);
	_hole_mjs.add_mj(mj7);
	_hole_mjs.add_mj(mj8);
	_hole_mjs.add_mj(mj9);
	_hole_mjs.add_mj(mj10);
	_hole_mjs.add_mj(mj11);
	_hole_mjs.add_mj(mj12);
	_hole_mjs.add_mj(mj13);
}

void Deck::pei_player_hole_mjs3(HoleMjs &_hole_mjs)
{
	
	_hole_mjs.clear();
	
	Mj mj1(W2);
	Mj mj2(W2);	
	Mj mj3(W2);
	
	Mj mj4(S9);
	Mj mj5(S9);
	Mj mj6(S9);
	
	Mj mj7(W6);
	Mj mj8(W6);
	Mj mj9(W6);
	
	Mj mj10(W4);
	Mj mj11(W4);
	Mj mj12(W4);
	
	Mj mj13(W9);		

	_hole_mjs.add_mj(mj1);
	_hole_mjs.add_mj(mj2);
	_hole_mjs.add_mj(mj3);
	_hole_mjs.add_mj(mj4);
	_hole_mjs.add_mj(mj5);
	_hole_mjs.add_mj(mj6);
	_hole_mjs.add_mj(mj7);
	_hole_mjs.add_mj(mj8);
	_hole_mjs.add_mj(mj9);
	_hole_mjs.add_mj(mj10);
	_hole_mjs.add_mj(mj11);
	_hole_mjs.add_mj(mj12);
	_hole_mjs.add_mj(mj13);
}

void Deck::pei_player_hole_mjs4(HoleMjs &_hole_mjs)
{
	
	_hole_mjs.clear();
	
	Mj mj1(W1);
	Mj mj2(W1);	
	Mj mj3(W1);
	
	Mj mj4(S2);
	Mj mj5(S2);
	Mj mj6(S2);
	
	Mj mj7(S4);
	Mj mj8(S4);
	Mj mj9(S4);
	
	Mj mj10(T7);
	Mj mj11(T7);
	Mj mj12(T7);
	
	Mj mj13(S8);		

	_hole_mjs.add_mj(mj1);
	_hole_mjs.add_mj(mj2);
	_hole_mjs.add_mj(mj3);
	_hole_mjs.add_mj(mj4);
	_hole_mjs.add_mj(mj5);
	_hole_mjs.add_mj(mj6);
	_hole_mjs.add_mj(mj7);
	_hole_mjs.add_mj(mj8);
	_hole_mjs.add_mj(mj9);
	_hole_mjs.add_mj(mj10);
	_hole_mjs.add_mj(mj11);
	_hole_mjs.add_mj(mj12);
	_hole_mjs.add_mj(mj13);
}


void Deck::get_common_mjs(CommonMjs &_comm_mjs)
{
	
	Mj mj;
	_comm_mjs.clear();	
	while( pop(mj) )
	{
		_comm_mjs.add_mj(mj);
	}
}

bool Deck::catch_spec(std::vector<Mj> vec)
{
	auto temp = mjs;
	for (auto& mj : vec)
	{
		auto itr = std::find(temp.begin(), temp.end(), mj);
		if (itr == temp.end())
		{
			return false;
		}
		temp.erase(itr);
	}
	mjs = temp;
	return true;
}



/*
void Deck::peipai_hole_mjs(HoleMjs &_hole_mjs)
{
	_hole_mjs.clear();
	
	Mj mj1(S1);
	Mj mj2(S1);	
	Mj mj3(S1);
	
	Mj mj4(S3);
	Mj mj5(S3);
	Mj mj6(S3);
	
	Mj mj7(S5);
	Mj mj8(S5);
	Mj mj9(S5);
	
	Mj mj10(S7);
	Mj mj11(S7);
	Mj mj12(S7);
	
	Mj mj13(S8);	

	
	_hole_mjs.add_mj(mj1);
	_hole_mjs.add_mj(mj2);
	_hole_mjs.add_mj(mj3);
	_hole_mjs.add_mj(mj4);
	_hole_mjs.add_mj(mj5);
	_hole_mjs.add_mj(mj6);
	_hole_mjs.add_mj(mj7);
	_hole_mjs.add_mj(mj8);
	_hole_mjs.add_mj(mj9);
	_hole_mjs.add_mj(mj10);
	_hole_mjs.add_mj(mj11);
	_hole_mjs.add_mj(mj12);
	_hole_mjs.add_mj(mj13);

}
void Deck::peipai_hole_mjs2(HoleMjs &_hole_mjs)
{
	_hole_mjs.clear();
	
		Mj mj1(S2);
	Mj mj2(S2);	
	Mj mj3(S2);
	
	Mj mj4(S4);
	Mj mj5(S4);
	Mj mj6(S4);
	
	Mj mj7(S6);
	Mj mj8(S6);
	Mj mj9(S6);
	
	Mj mj10(S8);
	Mj mj11(S8);
	Mj mj12(S8);
	
	Mj mj13(S9);	
	
	_hole_mjs.add_mj(mj1);
	_hole_mjs.add_mj(mj2);
	_hole_mjs.add_mj(mj3);
	_hole_mjs.add_mj(mj4);
	_hole_mjs.add_mj(mj5);
	_hole_mjs.add_mj(mj6);
	_hole_mjs.add_mj(mj7);
	_hole_mjs.add_mj(mj8);
	_hole_mjs.add_mj(mj9);
	_hole_mjs.add_mj(mj10);
	_hole_mjs.add_mj(mj11);
	_hole_mjs.add_mj(mj12);
	_hole_mjs.add_mj(mj13);
}

void Deck::peipai_hole_mjs3(HoleMjs &_hole_mjs)
{
	_hole_mjs.clear();
	
	Mj mj1(Zh);
	Mj mj2(Zh);	
	Mj mj3(Zh);
	
	Mj mj4(Fa);
	Mj mj5(Fa);
	Mj mj6(Fa);
	
	Mj mj7(Ba);
	Mj mj8(Ba);
	Mj mj9(Ba);
	
	Mj mj10(T7);
	Mj mj11(T7);
	Mj mj12(T7);
	
	Mj mj13(T9);	
	
	_hole_mjs.add_mj(mj1);
	_hole_mjs.add_mj(mj2);
	_hole_mjs.add_mj(mj3);
	_hole_mjs.add_mj(mj4);
	_hole_mjs.add_mj(mj5);
	_hole_mjs.add_mj(mj6);
	_hole_mjs.add_mj(mj7);
	_hole_mjs.add_mj(mj8);
	_hole_mjs.add_mj(mj9);
	_hole_mjs.add_mj(mj10);
	_hole_mjs.add_mj(mj11);
	_hole_mjs.add_mj(mj12);
	_hole_mjs.add_mj(mj13);
}


void Deck::test_hupai()
{
	fill();
    shuffle(23);
    HoleMjs _hole_mjs;
	
    //get_player_hole_mjs(_hole_mjs);
    peipai_hole_mjs(_hole_mjs);
	Mj::sort_by_ascending(_hole_mjs.mjs);
	Mj::dump_mjs(_hole_mjs.mjs);
	if (_hole_mjs.check_hupai())
	{
		printf("hu succ.\n");
	}
	else
	{
		printf("hu error.\n");
	}
}

void Deck::test_tingpai()
{
	fill();
    shuffle(23);
    HoleMjs _hole_mjs;
	
    peipai_hole_mjs(_hole_mjs);
	//Mj::sort_by_ascending(_hole_mjs.mjs);
	Mj::dump_mjs(_hole_mjs.mjs);
	std::vector<SLIANG> v_sliang;

	
	if (_hole_mjs.check_tingpai(v_sliang))
	{
		printf("can tingpai .\n");
		for (unsigned int i=0; i<v_sliang.size(); i++)
		{
			cout << "ting_mj:" << v_sliang[i].outmj.val << endl;
			cout << "v_gai_mjs:" << endl;
			for (unsigned int j=0; j<v_sliang[i].v_gai_mjs.size(); j++)
			{
				cout << v_sliang[i].v_gai_mjs[j].val << endl;
			}
		}
		cout << endl;
		//Mj::dump_mjs(pick_out_mj,"out_mj_can_ting_mjs");
	}
	else
	{
		printf("can no ting pai.\n");
	}
}

void Deck::test_pengpenghu()
{
	fill();
	shuffle(23);
	HoleMjs _hole_mjs;
	peipai_hole_mjs(_hole_mjs);
	//Mj::sort_by_ascending(_hole_mjs.mjs);
	Mj::dump_mjs(_hole_mjs.mjs);
	if (_hole_mjs.pengpenghu(_hole_mjs.mjs))
	{
		printf("is pengpenghu.\n");
	}
	else
	{
		printf("is not pengpenghu.\n");
	}	
}

void Deck::test_qidui()
{
	fill();
	shuffle(23);
	HoleMjs _hole_mjs;
	peipai_hole_mjs(_hole_mjs);
	Mj::dump_mjs(_hole_mjs.mjs);

	int ret = _hole_mjs.qidui(_hole_mjs.mjs);
	
	if ( ret == 0 )
	{	
		printf("is not qidui.\n");
	}
	else if ( ret == 1 )
	{		
		printf("is nomol qidui.\n");
	}
	else if (ret == 2)
	{
		printf("is haohua qidui.\n");
	}
}
*/

#if 0
//cmd: g++ -o test mj.cpp deck.cpp _hole_mjs.cpp common_mjs.cpp log.cpp
int main()
{
   Deck deck;
   //deck.test_hupai();
   deck.test_tingpai();
   //deck.test_pengpenghu();
   //deck.test_qidui();
   //deck.test_yise();
   //deck.test_kwx();
}
#endif


